//---------------------------------------------------------------------
// Authors: jachymko
//
// Description: Static members tab expansion
//
// Creation Date: Dec 27, 2006
//
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text.RegularExpressions;

using BGShell.PowerShell.Commands;

namespace BGShell.PowerShell.TabExpansion.Handlers
{
    internal sealed class StaticExpressionHandler : ExpressionHandlerBase
    {
        public StaticExpressionHandler(GetTabExpansionCommand cmd) 
            : base(cmd)
        {
        }

        private void ExpandGetType(string typeName, string expression)
        {
            ExpandExpression('[' + typeName + ']', expression);            
        }

        private void ExpandInvoke(string typeName, string expression)
        {
            string lastChild;
            string[] children = SplitDots(expression, out lastChild);
            
            string left = BuildStaticExpression(typeName, children);

            if (children.Length == 0)
            {
                string script = "[Type]($args[0]) | Get-Member -Name $args[1] -Static";
                object[] args = new object[]
                {
                    typeName, lastChild + '*' 
                };

                Collection<PSObject> memberInfos = InvokeArgs(script, args);
                WriteExpansions(GetMemberNames(memberInfos, left, lastChild));
            }
            else
            {
                ExpandExpression(left, lastChild);
            }
        }

        public override bool TryExpand(string line, string word)
        {
            var match = _pattern.Match(word);
            
            if (match.Success)
            {
                string typeName = match.Groups["TypeName"].Value;
                string expression = match.Groups["Expression"].Value;
                bool invoke = match.Groups["Invoke"].Success;
                bool getType = match.Groups["GetType"].Success;

                if(invoke)
                {
                    ExpandInvoke(typeName, expression);
                }
                else if(getType)
                {
                    ExpandGetType(typeName, expression);
                }

                return false;
            }

            return true;
        }

        static readonly Regex _pattern = new Regex(@"(?x)
            \[ 
                (?<TypeName> [^\]]*)
            \]

            (
                (?<Invoke>::) | (?<GetType>\.)
            )

            (?<Expression>.*)");
    }
}
